/**
 * Physics adapter.
 */

include('box2d');

// Shortcuts to ease usage and reading.
var
  b2Vec2 = Box2D.Common.Math.b2Vec2,
  b2AABB = Box2D.Collision.b2AABB,
  b2BodyDef = Box2D.Dynamics.b2BodyDef,
  b2Body = Box2D.Dynamics.b2Body,
  b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
  b2Fixture = Box2D.Dynamics.b2Fixture,
  b2World = Box2D.Dynamics.b2World,
  b2MassData = Box2D.Collision.Shapes.b2MassData,
  b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
  b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
  b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
  b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef;

// Constants for default values.
var ASTEROID_DENSITY = 1;
var ASTEROID_RESTITUTION = 1;

var XGBody = new_class(
  undefined,
  function(b) {
    this._b = b;
  },
  {
    getPosition: function() {
      return [this.getX(), this.getY()];
    },
    getX: function() { return this._b.GetPosition().x; },
    getY: function() { return this._b.GetPosition().y; },
    getAngle: function() { return this._b.GetAngle(); }
  });

new_class(
  'physics.Engine',
  function() {
    // No gravity, allow sleeping.
    this._w = new b2World(new b2Vec2(0, 0), true);
       var debugDraw = new b2DebugDraw();
		debugDraw.SetSprite(document.getElementById("debug-canvas").getContext("2d"));
		debugDraw.SetDrawScale(1);
		debugDraw.SetFillAlpha(1);
		debugDraw.SetLineThickness(1.0);
		debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
		this._w.SetDebugDraw(debugDraw);
  },
  {
    step: function() {
      this._w.Step(1 / 30, 10, 10);
      this._w.ClearForces();
      this._w.DrawDebugData();
    },
    add: function(shape, density) {
      if (!density) density = ASTEROID_DENSITY;
      var fixDef = new b2FixtureDef;
      fixDef.density = density;
      fixDef.friction = 0;
      fixDef.restitution = ASTEROID_RESTITUTION;
      fixDef.density = 1.0;
      fixDef.friction = 0.5;
      fixDef.restitution = 0.2;

      // Get the shape shape.
      fixDef.shape = shape.__createShape();

      var bodyDef = new b2BodyDef;
      bodyDef.type = b2Body.b2_dynamicBody;
      bodyDef.position.Set(shape.x, shape.y);
      var body = this._w.CreateBody(bodyDef);
      body.CreateFixture(fixDef);

      return new XGBody(body);
    },
    delete: function(body) {
      this._w.DestroyBody(body._b);
      body._b = null;
    }
  });
